//
//  VipCustomerManager.m
//  CustomerServer
//
//  Created by 涂俊 on 2019/4/14.
//  Copyright © 2019 Facebook. All rights reserved.
//

#import "VipCustomerManager.h"

#import <HelpDeskLite/HelpDeskLite.h>
#import "YCSuperSDK/SSDKDataKeys.h"
#import "HelpDeskLite/HDClientDelegate.h"
#import "ArgumentStore.h"
#import "VipCustomerViewController.h"
#import "ImManager.h"
#import "InitManager.h"
#import "UserInfo.h"

#import "SuperSDKPluginTools/SSDKPluginJsonUtil.h"
#import "SuperSDKPluginTools/SSDKPluginHttpUtil.h"
#import "SuperSDKPluginTools/SSDKPluginEncryptUtil.h"

#import "SCSWebViewController.h"

@interface VipCustomerManager() <HDClientDelegate>
@property(nonatomic, strong)NSLock *lock;
@end

@implementation VipCustomerManager

{
    NSDictionary *option;// 启动时系统回调的app的option
    UIViewController *rnViewController;
}

//单例
static VipCustomerManager *instance = nil;

+ (instancetype)getInstance {
    if (instance == nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[self alloc] init];
            instance.lock = [[NSLock alloc] init];
        });
    }
    return instance;
}

#pragma mark - public api 公开接口

// 初始化
- (void)init:(NSDictionary *)opt params:(NSDictionary *)param log:(BOOL)log {
    option = opt;
    // 游戏
    [[ArgumentStore getInstance] setBaseUrl:[param objectForKey:@"url"]];
    [[ArgumentStore getInstance] setLog:(log ? @"true" : @"false")];
    // 环信参数
    NSString *appkey = [param objectForKey:@"imAppKey"];
    NSString *tenantId = [param objectForKey:@"imTenantId"];
    [[ArgumentStore getInstance] setImAppKey:appkey];
    [[ArgumentStore getInstance] setImTenantId:tenantId];
    [[ArgumentStore getInstance] setConversationId:[param objectForKey:@"imConversationId"]];
    
    // Open
    [[ArgumentStore opInstance] setBaseUrl:[param objectForKey:@"url"]];
    [[ArgumentStore opInstance] setLog:(log ? @"true" : @"false")];
    [[ArgumentStore opInstance] setImAppKey:appkey];
    [[ArgumentStore opInstance] setImTenantId:tenantId];
    [[ArgumentStore opInstance] setConversationId:[param objectForKey:@"imConversationId"]];
    
    // 初始化客服sdk
    HDOptions *option = [[HDOptions alloc] init];
    option.appkey = appkey;
    option.tenantId = tenantId;
    option.enableConsoleLog = log; // 是否打开日志信息
    option.apnsCertName = @"";//SDK注册 APNS文件的名字, 需要与后台上传证书时的名字一一对应
    option.visitorWaitCount = YES; // 打开待接入访客排队人数功能
    option.showAgentInputState = YES; // 是否显示坐席输入状态
    HDClient *client = [HDClient sharedClient];
    HDError *initError = [client initializeSDKWithOptions:option];
    if (initError) {
        NSLog(@"环信初始化失败!");
        return;
    }
    // 将self 添加到SDK回调中，以便本类可以收到SDK回调
    [[HDClient sharedClient] addDelegate:self delegateQueue:nil];
    
    // 注册环信监听
    [self setupNotifiers];
    
    // 监听im消息
    [[ImManager getInstance]addImMessageObserver:self selector:@selector(receiveImMessage:)];
}

// 登录im
- (void)loginWithAppId:(NSString *)appId pubKey:(NSString *)pubKey uid:(NSString *)uid roleId:(NSString *)roleId {
    ArgumentStore *store = [ArgumentStore instanceForKey:appId];
    store.appId = appId;
    store.pubKey = pubKey;
    NSLog(@"登录环信!uid=%@,roleId=%@", uid, roleId);
    if (roleId == nil || uid == nil) {
        return;
    }
    // 重置初始化配置
//    [store setConfigInit:@""];
    
    // 先取本地uid对应的im账号密码，如果存在，则直接登录im
    NSArray *imAccount = [store getUserByUid:uid roleId:roleId];
    if (imAccount != nil) {
        // 异步,登录环信
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"玩家uid=%@,roleId=%@,本地记录存在，直接登录im", uid, roleId);
            BOOL result = [[InitManager getInstance] loginWithAppId:appId uid:uid roleId:roleId];
            
            if (self->_delegate) {
                [self->_delegate imLoginResult:result];
            }
        });
        return;
    }
    
    // 如果本地uid对应的im账号密码不存在，则请求初始化接口，再登录im
    [[InitManager getInstance] initWithAppId:appId uid:uid roleId:roleId callback:^(BOOL result) {
        if (result) {
            NSLog(@"玩家uid=%@,roleId=%@,本地记录不存在，初始化后再登录im", uid, roleId);
            BOOL result = [[InitManager getInstance] loginWithAppId:appId uid:uid roleId:roleId];
            if (self->_delegate) {
                [self->_delegate imLoginResult:result];
            }
        }
    }];
}


// 登录im
- (void)loginWithAppId:(NSString *)appId pubKey:(NSString *)pubKey uid:(NSString *)uid roleId:(NSString *)roleId result:(void(^)(BOOL))resultBlock {
    ArgumentStore *store = [ArgumentStore instanceForKey:appId];
    store.appId = appId;
    store.pubKey = pubKey;
    NSLog(@"登录环信!uid=%@,roleId=%@", uid, roleId);
    if (roleId == nil || uid == nil) {
        return;
    }
    // 重置初始化配置
//    [store setConfigInit:@""];
    
    // 先取本地uid对应的im账号密码，如果存在，则直接登录im
    NSArray *imAccount = [store getUserByUid:uid roleId:roleId];
    if (imAccount != nil) {
        // 异步,登录环信
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"玩家uid=%@,roleId=%@,本地记录存在，直接登录im", uid, roleId);
            BOOL result = [[InitManager getInstance] loginWithAppId:appId uid:uid roleId:roleId];
            if (resultBlock) {
                resultBlock(result);
            } else {
                if (resultBlock) {
                    resultBlock(result);
                }
            }
        });
        return;
    }
    
    // 如果本地uid对应的im账号密码不存在，则请求初始化接口，再登录im
    [[InitManager getInstance] initWithAppId:appId uid:uid roleId:roleId callback:^(BOOL result) {
        if (result) {
            NSLog(@"玩家uid=%@,roleId=%@,本地记录不存在，初始化后再登录im", uid, roleId);
            BOOL result = [[InitManager getInstance] loginWithAppId:appId uid:uid roleId:roleId];
            if (resultBlock) {
                resultBlock(result);
            }
        } else {
            if (resultBlock) {
                resultBlock(result);
            }
        }
    }];
}


// 打开客服系统界面
- (void)open:(NSDictionary *)param controller:(UIViewController *)controller {
    
    if (rnViewController != nil) {
        NSLog(@"已经打开客服，不能重复打开");
        return;
    }
    
    if (controller == nil) {
        NSLog(@"controller为空，无法打开客服");
        return;
    }
    
    ArgumentStore *store = ArgumentStore.current;
    if (store == nil) {
        [self alert:@"客服登录中，请稍后再试~"];
        return;
    }
    
//    if ([store.imLoginResult isEqual:@"logging"]) {
//        [self alert:@"客服登录失败中，请稍后再试~"];
//        return;
//    }
    
    if ([store.imLoginResult isEqual:@"fail"]) {
        [self alert:@"客服登录失败，请稍后再试~"];
        return;
    }
    
    // 保存用户和设备信息
    [store setUid:[param objectForKey:@"uid"]];
    [store setRoleId:[param objectForKey:@"roleId"]];
    [store setRoleName:[param objectForKey:@"roleName"]];
    [store setServerName:[param objectForKey:@"serverName"]];
    [store setGameName:[param objectForKey:@"gameName"]];
    [store setGameVersion:[param objectForKey:@"gameVersion"]];
    [store setChannelId:[param objectForKey:@"channelId"]];
    [store setSdkId:[param objectForKey:@"sdkId"]];
    [store setOs:[param objectForKey:@"os"]];
    [store setNetwork:[param objectForKey:@"network"]];
    [store setRom:[param objectForKey:@"rom"]];
    [store setRam:[param objectForKey:@"ram"]];
    
    NSString *url = @"https://customer-h5.sail2world.com";
    NSDictionary *config = [[[NSBundle mainBundle] infoDictionary] objectForKey:SSDK_L_CONFIG];
    if (config != nil) {
        NSDictionary *vipConfig = [config objectForKey:@"PLUGIN_Config_VipCustomer"];
        NSString *vipUrl = [vipConfig objectForKey:@"url"];
        if (vipUrl != nil && vipUrl.length > 0) {
            url = vipUrl;
        }
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        SCSWebViewController *webViewController = [[SCSWebViewController alloc] init];
        webViewController.url = url;
        self->rnViewController = webViewController;
        self->rnViewController.modalPresentationStyle = UIModalPresentationFullScreen;
        [controller presentViewController:self->rnViewController animated:YES completion:nil];
    });
}

- (void)alert:(NSString *)msg {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"好" style:UIAlertActionStyleCancel handler:nil];
        [alert addAction:cancel];
        [[self currentViewController] presentViewController:alert animated:YES completion:nil];
    });
}

// 关闭客服系统
- (void)close {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (self->rnViewController != nil) {
            [self->rnViewController dismissViewControllerAnimated:YES completion:nil];
            self->rnViewController = nil;
        }
    });
}

- (UIViewController *)getViewController {
    return rnViewController;
}


- (UIViewController *)currentViewController {
    UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
    UIViewController *vc = keyWindow.rootViewController;
    while (vc.presentedViewController) {
        vc = vc.presentedViewController;

        if ([vc isKindOfClass:[UINavigationController class]]) {
            vc = [(UINavigationController *)vc visibleViewController];
        } else if ([vc isKindOfClass:[UITabBarController class]]) {
            vc = [(UITabBarController *)vc selectedViewController];
        }
    }
    return vc;
}

//获取未读消息
- (NSNumber *)getUnReadMsgNum {
    return [[ImManager getInstance] getUnreadMsgNum];
}

//设置监听者
- (void)setDelegate:(id<VipCustomerDelegate>)delegate {
    _delegate = delegate;
}

#pragma mark - ImManager回调

// 收到im消息
- (void)receiveImMessage:(NSNotification*) notification {
    NSLog(@"VipCustomerManager收到im消息");
    if (rnViewController != nil) {
        NSLog(@"VipCustomerManager已经打开客服界面，不回调游戏");
        return;
    }
    if (_delegate) {
        NSArray *aMessages = [notification object];
        if (aMessages == nil) {
            NSLog(@"VipCustomerManager收到im消息为空,不回调游戏");
            return;
        }
        [_delegate receiveImMessage:aMessages];
        NSLog(@"VipCustomerManager收到im消息,回调游戏");
    }
}

#pragma mark - HDClientDelegate回调

- (void)connectionStateDidChange:(HConnectionState)aConnectionState {
    switch (aConnectionState) {
        case HConnectionConnected: {
            break;
        }
        case HConnectionDisconnected: {
            break;
        }
        default:
            break;
    }
}

#pragma mark - private method 私有方法


// 监听系统生命周期回调，以便将需要的事件传给SDK
- (void)setupNotifiers{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidEnterBackgroundNotif:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillEnterForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidFinishLaunching:)
                                                 name:UIApplicationDidFinishLaunchingNotification
                                               object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidBecomeActiveNotif:)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillResignActiveNotif:)
                                                 name:UIApplicationWillResignActiveNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appDidReceiveMemoryWarning:)
                                                 name:UIApplicationDidReceiveMemoryWarningNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appWillTerminateNotif:)
                                                 name:UIApplicationWillTerminateNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appProtectedDataWillBecomeUnavailableNotif:)
                                                 name:UIApplicationProtectedDataWillBecomeUnavailable
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appProtectedDataDidBecomeAvailableNotif:)
                                                 name:UIApplicationProtectedDataDidBecomeAvailable
                                               object:nil];
}

#pragma mark - notifiers
- (void)appDidEnterBackgroundNotif:(NSNotification*)notif{
    [[HDClient sharedClient] applicationDidEnterBackground:notif.object];
}

- (void)appWillEnterForeground:(NSNotification*)notif
{
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    [[HDClient sharedClient] applicationWillEnterForeground:notif.object];
}

- (void)appDidFinishLaunching:(NSNotification*)notif
{
    //    [[HDClient sharedClient] applicationdidfinishLounching];
    //   [[EaseMob sharedInstance] applicationDidFinishLaunching:notif.object];
}

- (void)appDidBecomeActiveNotif:(NSNotification*)notif
{
    //  [[EaseMob sharedInstance] applicationDidBecomeActive:notif.object];
}

- (void)appWillResignActiveNotif:(NSNotification*)notif
{
    //   [[EaseMob sharedInstance] applicationWillResignActive:notif.object];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"closeRecording" object:nil];
}

- (void)appDidReceiveMemoryWarning:(NSNotification*)notif
{
    //   [[EaseMob sharedInstance] applicationDidReceiveMemoryWarning:notif.object];
}

- (void)appWillTerminateNotif:(NSNotification*)notif
{
    //    [[EaseMob sharedInstance] applicationWillTerminate:notif.object];
}

- (void)appProtectedDataWillBecomeUnavailableNotif:(NSNotification*)notif
{
}

- (void)appProtectedDataDidBecomeAvailableNotif:(NSNotification*)notif
{
}

@end
